package model

import (
	"errors"
	"gorm.io/gorm"
)

type (
	UserMode struct {
		db *gorm.DB
	}

	User struct {
		Model
		UserType   int          `gorm:"not null;default:1"  gorm:"comment:用户类型 1.系统管理员 2.公司管理员 3.普通用户 4.终端 5 访客" json:"user_type"`
		Sex        int          `gorm:"type:int;default:0" json:"sex"` // 0 未知  1 男  2 女
		Birthday   string       `gorm:"type:char(10);default:''"json:"birthday"`
		UserName   string       `gorm:"type:varchar(32);index;not null" json:"user_name"`
		NickName   string       `gorm:"type:varchar(32);default:''" json:"nick_name"`
		PassWord   string       `gorm:"type:varchar(32);not null" json:"-"`
		Email      string       `gorm:"type:varchar(32);default:''" json:"email"`
		Phone      string       `gorm:"type:varchar(11);default:''" json:"phone" gorm:"comment:1 正常用户 .2 禁止登录"`
		Status     int          `gorm:"default:1" json:"status" gorm:"comment:1 正常用户 .2 禁止登录"`
		Salt       string       `gorm:"type:varchar(6);not null" json:"-"`
		CompanyId  int64        `json:"company_id"`
		FixedPhone string       `gorm:"type:varchar(16);default:''" json:"fixed_phone"` // 固话
		Facsimile  string       `gorm:"type:varchar(16);default:''" json:"facsimile"`   // 传真
		ExpireTime JsonNullTime `json:"expire_time"`                                    // 密码过期时间
		Desc       string       `gorm:"type:varchar(64);default:''"json:"desc"`         // 描述
		//IsGate     int          `gorm:"default:0" json:"is_gate"`                       // 是否拥有门禁
	}
)

func NewUserMode(db *gorm.DB) *UserMode {
	return &UserMode{
		db: db,
	}
}

func (m *UserMode) GetUserByUserName(username string) (User, error) {
	var userInfo User
	err := m.db.Where("user_name = ?", username).Take(&userInfo).Error
	if err != nil {
		return userInfo, err
	}
	return userInfo, nil
}
func (m *UserMode) GetById(uid int64) (User, error) {
	var user User
	err := m.db.Where("id = ?", uid).First(&user).Error
	return user, err
}
func (m *UserMode) AddUser(user *User) error {
	return m.db.Create(user).Error
}

func (m *UserMode) Update(id int64, user User) error {
	return m.db.Where("id = ?", id).Updates(&user).Error
}

func (m *UserMode) Del(id int64) error {
	return m.db.Where("id = ?", id).Delete(&User{}).Error
}

func (m *UserMode) Find(userName string, page int, size int) ([]User, error) {
	userList := make([]User, 0, 1)
	dbSession := m.db.Limit(size).Offset((page - 1) * size)
	if userName != "" {
		dbSession.Where("user_name like ?", userName+"%")
	}
	err := dbSession.Find(&userList).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return userList, nil
	} else if err != nil {
		return userList, err
	}
	return userList, nil
}

func (m *UserMode) FindCount(userName string) (int64, error) {
	var total int64
	dbSession := m.db.Model(&User{})
	if userName != "" {
		dbSession.Where("user_name like ?", userName+"%")
	}
	err := dbSession.Count(&total).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return total, nil
	} else if err != nil {
		return total, err
	}
	return total, nil
}

func (m *UserMode) FindGroupUserCount(groupIds []int64, userName string) (int64, error) {
	var total int64
	session := m.db.Model(&User{}).Joins("JOIN user_groups ON user_groups.Uid = users.id AND user_groups.group_id in ?", groupIds)
	if userName != "" {
		session.Where("users.user_name", userName+"%")
	}
	err := session.Count(&total).Group("users.id").Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return total, nil
	} else if err != nil {
		return total, err
	}
	return total, nil
}

// FindGroupUser 根据组来查询用户信息.
func (m *UserMode) FindGroupUser(groupIds []int64, userName string, page int, size int) ([]User, error) {
	userList := make([]User, 0, 1)
	session := m.db.Joins("JOIN user_groups ON user_groups.Uid = users.id AND user_groups.group_id in ?", groupIds)
	session.Limit(size).Offset((page - 1) * size).Group("users.id")
	if userName != "" {
		session.Where("users.user_name", userName+"%")
	}
	err := session.Find(&userList).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return userList, nil
	} else if err != nil {
		return userList, err
	}
	return userList, nil
}
